import os

import pandas as pd

from pandas import DataFrame

from src.event.EventBus import EventManager, Event
from src.monitor.LogcatMonitor import LogcatMonitor
from src.monitor.MeminfoMonitor import MeminfoMonitor
from src.monitor.VmstatMonitor import VmstatMonitor


class MonitorCenter:
    def __init__(self):
        self.device_name = None
        self.monitors = []
        self.monitors.append(VmstatMonitor('vmstat'))
        # self.monitors.append(LogcatMonitor('logcat'))
        # self.monitors.append(MeminfoMonitor('Meminfo'))

        self._normalize = False

    def get_connected_ip_address(self):
        return self.device_name;

    def start(self, device_name='0.0.0.0'):
        print('Start MonitorCenter')
        self.device_name = device_name

        for monitor in self.monitors:
            print('  > %s' % monitor.name)
            monitor.start(device_name)

    def stop(self):
        print('Stop MonitorCenter')
        for monitor in self.monitors:
            print('  %s> ' % monitor.name)
            monitor.stop()

    def state(self):
        for monitor in self.monitors:
            if monitor.state() is True:
                return 'Running'
            else:
                return 'Stopped'

    def retrieve_data(self):
        dfs = []
        for monitor in self.monitors:
            dfs.append(monitor.data)

        source: DataFrame = pd.concat(dfs, sort=True)

        result = source.copy()
        result.sort_index(inplace=True)

        if self._normalize:
            result = self.normalize(result)

        result.fillna(method='ffill', inplace=True)

        return result

    def set_normalize(self, b):
        self._normalize = b
        EventManager.emit(Event(Event.ON_CHART_UPDATE))

    def get_normalize(self):
        return self._normalize

    @staticmethod
    def normalize(df):
        result = df.copy()

        result.fillna(method='ffill', inplace=True)

        for feature_name in df.columns:
            max_value = df[feature_name].max()
            min_value = df[feature_name].min()

            result[feature_name] = df[feature_name] / max_value

        return result
